<?php

namespace app\index\controller;

use app\index\job\JobActivity;
use DOMDocument;
use Ramsey\Uuid\Guid\Guid;
use think\Cache;
use think\Controller;
use think\Db;
use think\Loader;
use think\Queue;
use think\Request;
use think\Validate;

class Api extends Controller
{
    private $sessionId;
    private $cookie; // 视频号登录cookie

    public function __construct()
    {
        if (session('accountId') > 0) {
            $account_info = Db::name('account')->field('sessionId,cookie')->where('id', session('accountId'))->find();

            $this->sessionId = $account_info['sessionId'] ? : '';
            $this->cookie = $account_info['cookie'] ? : '';
        }
    }

    public function setAccountCookie()
    {
        $input = Request()->param();

        $id = $input['id'];
        $cookie = $input['cookie'];

        if (empty($id) || empty($cookie)) apiReturn(2, '重新登录失败');

        $res = Db::name('account')->where('id', $id)->update(['cookie' => $cookie, 'update_time' => time()]);
        if ($res) {
            apiReturn(1, '重新登录成功');
        } else {
            apiReturn(2, '重新登录失败');
        }

    }

    /**
     * 获取headers
     * @param int $type 1:评论 2:私信
     * @return array
     * */
    public function getHeaders($type = 1)
    {
        $referer = $type == 1 ? "https://channels.weixin.qq.com/platform/comment" : "https://channels.weixin.qq.com/micro/interaction/private_msg";

        $headers = [
            "Accept: application/json, text/plain, */*",
            "Accept-Language: zh-CN,zh;q=0.9,en;q=0.8",
            "Connection: keep-alive",
            "Content-Type: application/json",
            "Cookie: $this->cookie",
            "Origin: https://channels.weixin.qq.com",
            "Referer: $referer",
            "Sec-Fetch-Dest: empty",
            "Sec-Fetch-Mode: cors",
            "Sec-Fetch-Site: same-origin",
            "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
            "X-WECHAT-UIN: 3802017021",
            "finger-print-device-id: 658104b43f6602ad8cb518a27f60f6b6",
            "sec-ch-ua: \"Google Chrome\";v=\"131\", \"Chromium\";v=\"131\", \"Not_A Brand\";v=\"24\"",
            "sec-ch-ua-mobile: ?0",
            "sec-ch-ua-platform: \"Windows\"",
        ];

        return $headers;
    }

    /**
     * 发送curl请求
     * @param string $url
     * @param string $jsonData
     * @param int    $type 1:评论 2:私信
     * */
    public function sendCurl($url, $jsonData, $type = 1)
    {
        // 初始化 cURL 会话
        $ch = curl_init();
        // 设置 cURL 选项
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders($type));
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonData);

        // 执行请求并获取响应
        $response = curl_exec($ch);

        // 检查 cURL 错误
        if (curl_errno($ch)) return false;

        // 关闭 cURL 会话
        curl_close($ch);

        return $response;
    }

    /**
     * 切换视频号
     * */
    public function changeAccount()
    {
        $input = Request()->param();

        $id = $input['id'];

        if (empty($id)) apiReturn(2, '参数错误');

        $account = Db::name('account')->where(['id' => $id, 'user_id' => session('id')])->find();
        if (empty($account)) apiReturn(2, '切换失败');

        session('accountId', $id);
        Db::name('account')->where('id', $id)->setField('last_use_time', time());

        apiReturn(1, '切换成功');
    }

    // 视频号视频列表
    public function videoList($page = 1, $pagesize = 10)
    {
        // 设置请求 URL
        $url = "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/post/post_list?_rid=67504de0-f94db71b";

        // 设置 POST 数据
        $data = [
            "pageSize" => $pagesize,
            "currentPage" => $page,
            "onlyUnread" => false,
            "userpageType" => 13,
            "needAllCommentCount" => true,
            "forMcn" => false,
            "timestamp" => round(microtime(true) * 1000),
            "_log_finder_uin" => "",
            "_log_finder_id" => "v2_{$this->sessionId}@finder",
            "rawKeyBuff" => null,
            "pluginSessionId" => null,
            "scene" => 7,
            "reqScene" => 7,
        ];

        // 将数据编码为 JSON 格式
        $jsonData = json_encode($data);

        $response = $this->sendCurl($url, $jsonData, 1);
        if ($response === false) apiReturn(2, '当前视频号凭证已过期');

        $return_data = json_decode($response, true);
        if ($return_data['errCode'] != 0) apiReturn(2, '当前视频号凭证已过期');

        if ($return_data['errCode'] == 0) {
            $totalCount = $return_data['data']['totalCount'];// 总条数
            $pageCount = ceil($totalCount / $pagesize);      // 总页数

            $list = $return_data['data']['list'];// 视频列表
            if ($list) {
                $data = [];
                $put_data = [];
                foreach ($list as &$v) {
                    $count = Db::name('video')->where('exportId', $v['exportId'])->count();
                    if ($count == 0) {
                        $thumbUrl = $this->getWechatPicture($v['desc']['media'][0]['thumbUrl'], 'thumbUrl');
                        $thumbUrl = $thumbUrl !== false ? $thumbUrl : $v['desc']['media'][0]['thumbUrl'];

                        $coverUrl = $this->getWechatPicture($v['desc']['media'][0]['coverUrl'], 'coverUrl');
                        $coverUrl = $coverUrl !== false ? $coverUrl : $v['desc']['media'][0]['coverUrl'];

                        $push_data = [
                            'login_sessionId' => $this->sessionId,
                            'exportId' => $v['exportId'],
                            'thumbUrl' => $thumbUrl,
                            'description' => $v['desc']['description'],
                            'url' => $v['desc']['media'][0]['url'],
                            'coverUrl' => $coverUrl,
                            'commentCount' => $v['commentCount'],
                            'likeCount' => $v['likeCount'],
                            'readCount' => $v['readCount'],
                            'videoPlayLen' => $v['desc']['media'][0]['videoPlayLen'],
                            'createTime' => $v['createTime'],
                            'update_time' => time()
                        ];

                        $data[] = $push_data;
                        $put_data[] = $push_data;
                    }
                }
                if ($data) {
                    $res = Db::name('video')->insertAll($data);
                    if ($res) {
                        file_put_contents(RUNTIME_PATH . 'getVideoSuccess.txt', json_encode($put_data, JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND);
                        if ($pageCount > $page) {
                            sleep(3);
                            $this->videoList($page + 1, $pagesize);
                        }
                    } else {
                        file_put_contents(RUNTIME_PATH . 'getVideoError.txt', 'exportId => ' . $data[0]['exportId'] . '；' . '；page => ' . $page . '；' . date('Y-m-d H:i:s') . '采集数据失败' . PHP_EOL, FILE_APPEND);
                        apiReturn(2, '失败');
                    }
                } else {
                    if ($pageCount > $page) {
                        sleep(3);
                        $this->videoList($page + 1, $pagesize);
                    }
                }
            } else {
                file_put_contents(RUNTIME_PATH . 'getVideoError.txt', 'exportId => ' . $data[0]['exportId'] . '；' . '；page => ' . $page . '；' . date('Y-m-d H:i:s') . '采集数据失败' . PHP_EOL, FILE_APPEND);
                apiReturn(2, '失败');
            }
        } else {
            file_put_contents(RUNTIME_PATH . 'getVideoError.txt', 'exportId => ' . $data[0]['exportId'] . '；' . '；page => ' . $page . '；' . date('Y-m-d H:i:s') . '采集数据失败' . PHP_EOL, FILE_APPEND);
            apiReturn(2, '失败');
        }

        apiReturn(1, '成功');
    }

    /**
     * 保存微信图片至服务器
     * */
    public function getWechatPicture($url, $type = 'thumbUrl')
    {
        $path = '/uploads/wechatPicture/' . $type . '/';
        $dir_res = createDirectory('.' . $path);
        if (!$dir_res) return false;

        // 初始化 cURL 会话
        $ch = curl_init($url);

        // 设置 cURL 选项
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);  // 返回图片内容
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);  // 跟踪重定向
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 禁用 SSL 验证
        curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36');

        // 执行 cURL 请求并获取图片内容
        $imageData = curl_exec($ch);

        // 检查 cURL 请求是否成功
        if ($imageData === false) {
            $res = false;
        } else {
            // 保存图片到服务器
            $savePath = date('His') . rand(100000, 999999) . '.jpg';
            $savePath = $path . $savePath;
            file_put_contents('.' . $savePath, $imageData);

            $res = $savePath;
        }

        // 关闭 cURL 会话
        curl_close($ch);

        return $res;
    }

    /**
     * 获取评论列表
     * */
    public function getVideoCommentList($exportId)
    {
        if ($exportId) {
            // 设置请求 URL
            $url = "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/comment/comment_list?_rid=67505d20-43769075";

            // 设置 POST 数据
            $data = [
                "lastBuff" => "",
                "exportId" => $exportId,
                "commentSelection" => false,
                "forMcn" => false,
                "timestamp" => round(microtime(true) * 1000),
                "_log_finder_uin" => "",
                "_log_finder_id" => "v2_{$this->sessionId}@finder",
                "rawKeyBuff" => null,
                "pluginSessionId" => null,
                "scene" => 7,
                "reqScene" => 7,
            ];

            // 将数据编码为 JSON 格式
            $jsonData = json_encode($data);

            $response = $this->sendCurl($url, $jsonData, 1);
            if ($response === false) apiReturn(2, '当前视频号凭证已过期');

            $return_data = json_decode($response, true);
            if ($return_data['errCode'] != 0) apiReturn(2, '登录失效');

            return $return_data;
        }
    }

    // 加载更多评论
    public function loadMoreCommentList($exportId, $commentId, $lastBuff)
    {
        if ($exportId && $commentId && $lastBuff) {
            // 设置请求 URL
            $url = "https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/comment/comment_list?_rid=6767c9a2-193ea31c";

            // 设置 POST 数据
            $data = [
                "commentSelection" => false,
                "exportId" => $exportId,
                "forMcn" => false,
                "lastBuff" => $lastBuff,
                "pluginSessionId" => null,
                "rawKeyBuff" => null,
                "reqScene" => 7,
                "rootCommentId" => $this->getRootCommentId($commentId),
                "scene" => 7,
                "timestamp" => round(microtime(true) * 1000),
                "_log_finder_id" => "v2_{$this->sessionId}@finder",
                "_log_finder_uin" => "",
            ];

            // 将数据编码为 JSON 格式
            $jsonData = json_encode($data);

            $response = $this->sendCurl($url, $jsonData, 1);
            if ($response === false) apiReturn(2, '当前视频号凭证已过期');

            $return_data = json_decode($response, true);
            if ($return_data['errCode'] != 0) apiReturn(2, '登录失效');

            return $return_data;
        }
    }

    public function loadMoreTwoLevel($videoExportId, $commentId, $lastBuff, &$twoLevelList = [])
    {
        $load_return_data = $this->loadMoreCommentList($videoExportId, $commentId, $lastBuff);
        if ($load_return_data['errCode'] == 0) {
            $list = $load_return_data['data']['comment'];

            if ($load_return_data['downContinueFlag'] == 1) {
                return $this->loadMoreTwoLevel($videoExportId, $commentId, $lastBuff);
            } else {
                return array_merge($twoLevelList, $list);
            }
        } else {
            return [];
        }
    }

    // 视频号评论列表入库【更新评论数据】
    public function videoCommentList()
    {
        $input = Request()->param();

        $exportId = $input['exportId'];
        $where = [];
        if ($exportId) $where['exportId'] = $exportId;

        $video_list = Db::name('video')->where($where)->select();
        if ($video_list) {
            $data = [];

            Db::startTrans();
            try {
                foreach ($video_list as &$value) {
                    $videoExportId = $value['exportId'];
                    $return_data = $this->getVideoCommentList($videoExportId);

                    $comment_count = $return_data['data']['commentCount'];
                    if ($return_data['errCode'] == 0) {
                        $list = $return_data['data']['comment'];// 评论列表

                        // 提取某一个视频所有评论的 commentId
                        $videoCommentIdArr = extractCommentIds($list);
                        if (!empty($videoCommentIdArr)) {
                            // 删除该视频中不在$videoCommentIdArr范围的评论数据
                            Db::name('comment')->where('video_id', $value['id'])->whereNotIn('commentId', $videoCommentIdArr)->delete();
                        }

                        if ($list) {
                            foreach ($list as &$val) {
                                $count = Db::name('comment')->where('commentId', $val['commentId'])->count();
                                if ($count == 0) {
                                    $data[] = [
                                        'login_sessionId' => $this->sessionId,
                                        'video_id' => $value['id'],
                                        'commentId' => $val['commentId'],
                                        'commentNickname' => $val['commentNickname'],
                                        'commentHeadurl' => $val['commentHeadurl'],
                                        'commentContent' => $val['commentContent'],
                                        'commentCreatetime' => $val['commentCreatetime'],
                                        'commentLikeCount' => $val['commentLikeCount'],
                                        'visibleFlag' => $val['visibleFlag'],
                                        'readFlag' => $val['readFlag'] ? : 0,
                                        'likeFlag' => $val['likeFlag'],
                                        'lastBuff' => $val['lastBuff'],
                                        'replyCommentId' => '',
                                        'comment' => json_encode($val, JSON_UNESCAPED_UNICODE), // 原始评论数据
                                        'update_time' => time()
                                    ];
                                }

                                $levelTwoComment = $val['levelTwoComment'];

                                /*if ($val['downContinueFlag'] == 1) {
                                    // 加载更多levelTwoComment
                                    $allTwoLevelList = $this->loadMoreTwoLevel($videoExportId, $val['commentId'], $val['lastBuff']);
                                    $levelTwoComment = array_merge($levelTwoComment, $allTwoLevelList);
                                }*/

                                $val['levelTwoComment'] = [];
                                if ($levelTwoComment) {
                                    foreach ($levelTwoComment as &$v) {
                                        $count = Db::name('comment')->where('commentId', $v['commentId'])->count();
                                        if ($count == 0) {
                                            $v['levelTwoComment'] = [];
                                            $data[] = [
                                                'login_sessionId' => $this->sessionId,
                                                'video_id' => $value['id'],
                                                'commentId' => $v['commentId'],
                                                'commentNickname' => $v['commentNickname'],
                                                'commentHeadurl' => $v['commentHeadurl'],
                                                'commentContent' => $v['commentContent'],
                                                'commentCreatetime' => $v['commentCreatetime'],
                                                'commentLikeCount' => $v['commentLikeCount'],
                                                'visibleFlag' => $v['visibleFlag'],
                                                'readFlag' => $v['readFlag'] ? : 0,
                                                'likeFlag' => $v['likeFlag'],
                                                'lastBuff' => $val['lastBuff'],
                                                'replyCommentId' => $v['replyCommentId'] ? : '',
                                                'comment' => json_encode($v, JSON_UNESCAPED_UNICODE), // 原始评论数据
                                                'update_time' => time()
                                            ];
                                        }
                                    }
                                }
                            }
                        }
                        //                    sleep(5);
                    }
                    Db::name('video')->where(['id' => $value['id']])->setField('commentCount', $comment_count);
                }
                Db::name('comment')->insertAll($data);

                Db::commit();
                apiReturn(1, '更新评论成功');
            } catch (\Exception $e) {
                Db::rollback();
                apiReturn(2, '更新评论失败' . $e->getMessage());
            }
        }
    }

    /**
     * 获取rootCommentId
     * */
    public function getRootCommentId($commentId)
    {
        $commentId = Db::name('comment')->where(['commentId' => $commentId])->value('replyCommentId');
        if ($commentId) {
            return $this->getRootCommentId($commentId);
        } else {
            return $commentId;
        }
    }

    /**
     * 向视频号发送网络请求
     * */
    public function sendCommentRequest($commentId, $msg, $comment, $exportId)
    {
        // 设置请求 URL
        $url = "https://channels.weixin.qq.com/cgi-bin/mmfinderassistant-bin/comment/create_comment?_rid=67505e8e-9ea4769f";

        $uuid = Guid::uuid4()->toString();
        // 设置 POST 数据
        $data = [
            "replyCommentId" => $commentId,
            "content" => $msg,
            "clientId" => $uuid,
            "rootCommentId" => $this->getRootCommentId($commentId),
            "comment" => json_decode($comment, true),
            "exportId" => $exportId,// 视频exportId
            "timestamp" => round(microtime(true) * 1000),
            "_log_finder_uin" => "",
            "_log_finder_id" => "v2_{$this->sessionId}@finder",
            "rawKeyBuff" => null,
            "pluginSessionId" => null,
            "scene" => 7,
            "reqScene" => 7,
        ];

        // 将数据编码为 JSON 格式
        $jsonData = json_encode($data);

        $response = $this->sendCurl($url, $jsonData, 1);

        return $response;
    }

    public function getCookie()
    {
        // 初始化 cURL 请求
        $ch = curl_init();

        // 设置请求 URL
        curl_setopt($ch, CURLOPT_URL, "https://channels.weixin.qq.com");

        // 设置 cURL 选项，模拟浏览器访问
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   // 获取响应结果
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);   // 自动跟随重定向
        curl_setopt($ch, CURLOPT_HEADER, true);           // 获取响应头
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);  // 禁用证书验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);  // 不验证证书主机

        // 设置 User-Agent，模拟浏览器请求
        curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36");

        // 设置 Accept-Encoding，支持 gzip、deflate 压缩内容
        curl_setopt($ch, CURLOPT_ENCODING, "gzip, deflate");

        // 设置请求头
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8",
            "Accept-Language: en-US,en;q=0.9,zh;q=0.8",
            "Connection: keep-alive",
            "Upgrade-Insecure-Requests: 1",
            "DNT: 1", // Do Not Track
            "Cache-Control: no-cache",
            "Pragma: no-cache"
        ]);

        // 执行请求
        $response = curl_exec($ch);

        // 获取响应的头部信息
        $headers = curl_getinfo($ch);

        // 输出响应头信息，看看是否有 Set-Cookie
        echo "Response Headers: \n";
        print_r($headers);

        // 获取并解析 cookies（从 Set-Cookie 中提取）
        preg_match_all('/Set-Cookie:\s*([^;]*)/i', $response, $matches);

        // 输出所有获取到的 cookies
        echo "Cookies: \n";
        print_r($matches[1]);

        // 获取页面内容（去除响应头部）
        $html_content = substr($response, $headers['header_size']);

        // 确保正确的字符编码，如果没有设置 charset，默认使用 UTF-8
        if (preg_match('/<meta.*?charset=["\']?([^"\'>]+)["\']?.*?>/i', $html_content, $matches)) {
            $charset = strtolower($matches[1]);
        } else {
            $charset = 'utf-8';  // 默认使用 UTF-8
        }

        // 如果字符集不是 UTF-8，进行编码转换
        if ($charset != 'utf-8') {
            $html_content = mb_convert_encoding($html_content, 'UTF-8', $charset);
        }

        echo "HTML Content: \n";
        echo $html_content;

        // 关闭 cURL 会话
        curl_close($ch);
    }

    // 评论
    public function comment()
    {
        $input = Request()->param();

        $commentId = $input['commentId'];
        $quickReplyId = $input['quickReplyId'];
        $msg = $input['msg'];

        if (!$commentId || !$msg) apiReturn(2, '缺少参数，发送失败');

        $comment_info = Db::name('comment')->where(['commentId' => $commentId])->find();
        if (empty($comment_info)) apiReturn(2, '评论不存在，发送失败');

        $exportId = Db::name('video')->where(['id' => $comment_info['video_id']])->value('exportId');
        if (empty($exportId)) apiReturn(2, '视频不存在，发送失败');

        // 增加快捷回复使用次数
        if ($quickReplyId > 0) Db::name('quick_reply')->where(['id' => $quickReplyId])->setInc('use_count');

        $response = $this->sendCommentRequest($commentId, $msg, $comment_info['comment'], $exportId);

        // 输出响应结果
        $return_data = json_decode($response, true);
        if ($return_data['errCode'] == 0) {
            Db::name('comment')->where(['commentId' => $commentId])->setField('is_reply', 1);

            apiReturn(1, '评论成功', $exportId);
        } else {
            apiReturn(2, '当前视频号凭证已过期');
        }
    }

    public function getCommentSon($commentId, &$son_list = [])
    {
        $list = Db::name('comment')->where(['replyCommentId' => $commentId])->order('commentCreatetime asc')->select();
        if ($list) {
            foreach ($list as &$val) {
                $val['commentCreatetime'] = date('Y-m-d H:i:s', $val['commentCreatetime']);
            }

            $son_list = array_merge($son_list, $list);
            return $this->getCommentSon($val['commentId'], $son_list);
        } else {
            return $son_list;
        }
    }

    /**
     * 从数据库获取评论数据
     * */
    public function getCommentToDB()
    {
        $input = Request()->param();

        $video_id = $input['video_id'];

        if (empty($video_id)) apiReturn(2, '缺少参数');

        $list = Db::name('comment')->where(['login_sessionId' => $this->sessionId, 'video_id' => $video_id, 'replyCommentId' => ''])->order('commentCreatetime desc')->select();
        if ($list) {
            foreach ($list as &$v) {
                $v['commentCreatetime'] = date('Y-m-d H:i:s', $v['commentCreatetime']);

                $son_list = $this->getCommentSon($v['commentId']);
                $v['son_list'] = $son_list;
            }
        }

        apiReturn(1, '获取数据成功', $list);
    }

    /**
     * 获取快捷回复
     * */
    public function getQuickReplyList()
    {
        $input = Request()->param();

        $commentId = $input['commentId'];

        $commentContent = Db::name('comment')->where(['commentId' => $commentId])->value('commentContent');
        if (empty($commentContent)) apiReturn(2, '评论不存在');

        $reply_list = getQuickReply($commentContent);

        if ($reply_list) {
            apiReturn(1, '获取数据成功', $reply_list);
        } else {
            apiReturn(2, '暂无数据');
        }
    }

    /**
     * AI优化快捷回复
     * */
    public function AIQuickReply()
    {
        $input = Request()->param();

        $msg = $input['msg'];

        if (empty($msg)) apiReturn(2, 'AI优化失败');

        $messages = [
            [
                'role' => 'system',
                'content' => '我是快捷回复优化助手，请问有什么可以帮您？'
            ], [
                'role' => 'user',
                'content' => '我有一个快捷回复，我想请你帮我优化一下，内容：' . $msg . '；请帮我遵循以下要求（1：不要用修辞手法，2：不要改变原意，3：通俗易通，4：直接给我优化后的内容）'
            ]
        ];

        $data = textGeneration($messages);
        if ($data) {
            $text = $data['output']['text'];
            if ($text) {

                apiReturn(1, '获取数据成功', $text);
            } else {
                apiReturn(2, 'AI优化失败');
            }
        } else {
            apiReturn(2, 'AI优化失败');
        }
    }

    /**
     * AI一键优化【评论】
     * */
    public function AICommonQuickReplyAll()
    {
        $input = Request()->param();

        $ids = $input['ids'];
        $quick_ids = $input['quick_ids'];

        if (empty($ids)) apiReturn(2, '请选择需要优化评论');
        if (count($ids) != count($quick_ids)) apiReturn(2, '参数有误');

        $where['id'] = ['in', $ids];

        $list = Db::name('comment')->where($where)->order('commentCreatetime asc')->select();
        if ($list) {
            foreach ($list as $k => $v) {
                $quick_id = $quick_ids[$k];
                if (empty($quick_id)) continue;

                $msg = Db::name('quick_reply')->where(['id' => $quick_id])->value('msg');
                if ($msg) {
                    Db::name('quick_reply')->where(['id' => $quick_id])->setInc('use_count');

                    $messages = [
                        [
                            'role' => 'system',
                            'content' => '我是快捷回复优化助手，请问有什么可以帮您？'
                        ], [
                            'role' => 'user',
                            'content' => '我有一个快捷回复，我想请你帮我优化一下，内容：' . $msg . '；请帮我遵循以下要求（1：不要用修辞手法，2：不要改变原意，3：通俗易通，4：直接给我优化后的内容）'
                        ]
                    ];
                    $data = textGeneration($messages);
                    $text = $data['output']['text'];
                    $AIMsg = $text ? : $msg;
                    $v['AIMsg'] = $AIMsg;

                    Db::name('comment')->where(['id' => $v['id']])->update(['AIMsg' => $AIMsg]);
                }
            }
        }

        apiReturn(1, 'AI一键优化完成', $list);
    }

    /**
     * 一键发送评论
     * */
    public function sendCommentAll()
    {
        $input = Request()->param();

        $ids = $input['ids'];

        if (empty($ids)) apiReturn(2, '请选择需要优化评论');

        $where['id'] = ['in', $ids];

        $list = Db::name('comment')->where($where)->order('commentCreatetime asc')->select();
        if ($list) {
            foreach ($list as &$v) {
                if (empty($v['comment']) || empty($v['id']) || empty($v['AIMsg'])) continue;

                $exportId = Db::name('video')->where(['id' => $v['video_id']])->value('exportId');
                if (empty($exportId)) continue;

                $response = $this->sendCommentRequest($v['commentId'], $v['AIMsg'], $v['comment'], $exportId);
                // 输出响应结果
                $return_data = json_decode($response, true);
                if ($return_data['errCode'] == 0) {
                    Db::name('comment')->where(['id' => $v['id']])->setField('is_reply', 1);

                    sleep(3);
                } else {
                    continue;
                }
            }
        }

        apiReturn(1, '一键评论完成', $exportId);
    }

    /**
     * 保存回复内容
     * */
    public function saveComment()
    {
        $input = Request()->param();

        $id = $input['id'];
        $msg = $input['msg'];

        if (empty($id)) apiReturn(2, 'ID缺失');
        if (empty($msg)) apiReturn(2, '回复内容缺失');

        Db::name('comment')->where(['id' => $id])->setField('AIMsg', $msg);
        apiReturn(1, '保存成功');
    }


    /**************************************以下代码均为【私信】代码*************************************/

    public function insertAllChatMsg($msg_list, $login_sessionId = '')
    {
        $msg_data = [];
        $sessionId = [];
        foreach ($msg_list as &$v) {
            if ($v['msgType'] == 1) {
                $rawContent = $v['rawContent'];
            } elseif ($v['msgType'] == 3) {
                // 图片消息
                $doc = new DOMDocument();
                $doc->loadXML($v['rawContent']);

                // 将 XML 转换为字符串
                $rawContent = $doc->saveXML();
            }

            $msg_count = Db::name('chat_msg')->where(['svrMsgId' => $v['svrMsgId']])->count();
            if ($msg_count == 0) {
                $msg_data[] = [
                    'login_sessionId' => $login_sessionId ? : $this->sessionId,
                    'fromUsername' => $v['fromUsername'],
                    'msgType' => $v['msgType'],
                    'rawContent' => $rawContent,
                    'sessionId' => $v['sessionId'],
                    'svrMsgId' => $v['svrMsgId'],
                    'toUsername' => $v['toUsername'],
                    'ts' => $v['ts'],
                    'imgMsg' => $v['imgMsg'] ? json_encode($v['imgMsg'], JSON_UNESCAPED_UNICODE) : ''
                ];
            }

            $user_count = Db::name('chat_user')->where(['sessionId' => $v['sessionId']])->count();
            if ($user_count == 0) {
                $sessionId[] = $v['sessionId'];
            }
        }

        Db::name('chat_msg')->insertAll(array_reverse($msg_data));

        // 添加用户数据
        $sessionId = array_values(array_unique($sessionId));
        $this->insertUserData($sessionId);
    }

    // 获取私信列表
    public function getHistoryMsg()
    {
        // 设置请求 URL
        $url = "https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/private-msg/get-history-msg";

        // 设置 POST 数据
        $data = [
            "pluginSessionId" => null,
            "rawKeyBuff" => null,
            "reqScene" => 7,
            "scene" => 7,
            "timestamp" => round(microtime(true) * 1000),
            "_log_finder_id" => "v2_{$this->sessionId}@finder",
            "_log_finder_uin", "",
        ];

        // 将数据编码为 JSON 格式
        $jsonData = json_encode($data);

        $response = $this->sendCurl($url, $jsonData, 2);
        if ($response === false) apiReturn(2, '当前视频号凭证已过期');

        $return_data = json_decode($response, true);
        if ($return_data['errCode'] != 0) apiReturn(2, '当前视频号凭证已过期');

        $msg_list = $return_data['data']['msg'];

        if ($msg_list) {
            // 添加私信消息
            $this->insertAllChatMsg($msg_list);
        }

        apiReturn(1, '成功');
    }

    public function newChatTime($sessionId, $login_session = '', $join = true)
    {
        $login_session = $login_session ? : $this->sessionId;

        if ($join) {
            $ts = Db::name('chat_user wu')
                ->join('we_chat_msg wm', 'wm.fromUsername = wu.username OR wm.toUsername = wu.username', 'LEFT')
                ->where('wu.login_sessionId', $login_session)
                ->where('wu.sessionId', $sessionId)
                ->max('wm.ts');
        } else {
            $ts = Db::name('chat_msg')
                ->where('login_sessionId', $login_session)
                ->where('fromUsername|toUsername', "fv1_{$sessionId}@findermsgstranger")
                ->max('ts');
        }

        return $ts;
    }

    /**
     * 获取用户数据
     * @param string $sessionId       好友sessionId
     * @param string $login_sessionId 当前登录账号sessionId
     * */
    public function insertUserData($sessionId, $login_sessionId = '')
    {
        $login_sessionId = $login_sessionId ? : $this->sessionId;

        // 设置请求 URL
        $url = "https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/private-msg/get-session-info";

        // 设置 POST 数据
        $data = [
            "pluginSessionId" => null,
            "rawKeyBuff" => null,
            "reqScene" => 7,
            "scene" => 7,
            "sessionId" => $sessionId,
            "timestamp" => round(microtime(true) * 1000),
            "_log_finder_id" => "v2_{$login_sessionId}@finder",
            "_log_finder_uin", "",
        ];

        // 将数据编码为 JSON 格式
        $jsonData = json_encode($data);

        $response = $this->sendCurl($url, $jsonData, 2);

        if ($response === false) apiReturn(2, '当前视频号凭证已过期');

        $return_data = json_decode($response, true);
        if ($return_data['errCode'] != 0) return false;

        $user_list = $return_data['data']['sessionInfo'];

        if ($user_list) {
            $insert_user = [];
            foreach ($user_list as &$v) {
                $friend_sessionId = str_replace('@findermsg', '', $v['sessionId']);

                //                file_put_contents(RUNTIME_PATH . 'sessionId.txt', $friend_sessionId . PHP_EOL, FILE_APPEND);
                //                file_put_contents(RUNTIME_PATH . '$ts.txt', $ts . PHP_EOL, FILE_APPEND);


                $ts = $this->newChatTime($friend_sessionId, $login_sessionId, false);

                $user_info = Db::name('chat_user')->where(['login_sessionId' => $login_sessionId, 'sessionId' => $friend_sessionId])->find();
                if (!empty($user_info)) {
                    Db::name('chat_user')->where('id', $user_info['id'])->setField('new_msg_time', $ts);
                } else {
                    if (empty($friend_sessionId)) return false;

                    $insert_user[] = [
                        'login_sessionId' => $login_sessionId,
                        'sessionId' => $friend_sessionId,
                        'username' => $v['username'],
                        'nickname' => $v['nickname'],
                        'headImgUrl' => $v['headImgUrl'],
                        'sex' => $v['extInfo']['sex'],
                        'new_msg_time' => $ts,
                    ];
                }
            }
            Db::name('chat_user')->insertAll($insert_user);
        }

        return true;
    }

    public function getChatContentToDb()
    {
        $input = Request()->param();

        $user_id = $input['user_id'];

        if (empty($user_id)) apiReturn(2, '参数缺失');

        // 好友的sessionId
        $friend_sessionId = Db::name('chat_user')->where(['id' => $user_id])->value('sessionId');

        if (empty($user_id)) apiReturn(2, '获取聊天数据失败');

        $me_sessionId = $this->sessionId;

        $friend_username = "fv1_{$friend_sessionId}@findermsgstranger";
        $me_username = "v2_{$me_sessionId}@finder";

        $list = Db::name('chat_msg')
            ->field('id,rawContent,fromUsername')
            ->where('login_sessionId', $me_sessionId)
            ->where('msgType', 1)
            ->where(function ($query) use ($friend_username, $me_username) {
                $query->where(function ($query) use ($friend_username, $me_username) {
                    $query->where('fromUsername', $friend_username)
                        ->where('toUsername', $me_username);
                })
                    ->whereOr(function ($query) use ($friend_username, $me_username) {
                        $query->where('fromUsername', $me_username)
                            ->where('toUsername', $friend_username);
                    });
            })
            ->order('ts asc')
            ->select();
        if ($list) {
            foreach ($list as &$v) {
                if (strpos($v['fromUsername'], $me_sessionId) !== false) {
                    // 自己发的消息
                    $avatar = Db::name('comment')->where(['visibleFlag' => 1, 'login_sessionId' => $me_sessionId])->value('commentHeadurl');
                    $type = 'me';
                } else {
                    // 别人发的消息
                    $avatar = Db::name('chat_user')->where(['login_sessionId' => $me_sessionId, 'sessionId' => $friend_sessionId])->value('headImgUrl');
                    $type = 'friend';
                }

                $v['avatar'] = $avatar ? : '';
                $v['type'] = $type;
            }
        }

        $last_rawContent = $list[count($list) - 1]['rawContent'];
        $reply_list = getQuickReply($last_rawContent);

        $data = [
            'list' => $list,
            'reply_list' => $reply_list
        ];


        apiReturn(1, '获取聊天数据成功', $data);
    }


    /**
     * AI一键优化【私信】
     * */
    public function AIChatQuickReplyAll()
    {
        $input = Request()->param();

        $ids = $input['ids'];
        $quick_ids = $input['quick_ids'];

        if (empty($ids)) apiReturn(2, '请选择需要优化评论');
        if (count($ids) != count($quick_ids)) apiReturn(2, '参数有误');

        $where['id'] = ['in', $ids];

        $list = Db::name('chat_user')->where($where)->orderRaw('FIELD(id, ' . implode(',', $ids) . ')')->select();
        if ($list) {
            foreach ($list as $k => $v) {
                $quick_id = $quick_ids[$k];
                if (empty($quick_id)) continue;

                $msg = Db::name('quick_reply')->where(['id' => $quick_id])->value('msg');
                if ($msg) {
                    Db::name('quick_reply')->where(['id' => $quick_id])->setInc('use_count');

                    $messages = [
                        [
                            'role' => 'system',
                            'content' => '我是快捷回复优化助手，请问有什么可以帮您？'
                        ], [
                            'role' => 'user',
                            'content' => '我有一个快捷回复，我想请你帮我优化一下，内容：' . $msg . '；请帮我遵循以下要求（1：不要用修辞手法，2：不要改变原意，3：通俗易通，4：直接给我优化后的内容）'
                        ]
                    ];
                    $data = textGeneration($messages);
                    $text = $data['output']['text'];
                    $AIMsg = $text ? : $msg;
                    $v['AIMsg'] = $AIMsg;

                    Db::name('chat_user')->where(['id' => $v['id']])->update(['AIMsg' => $AIMsg]);
                }
            }
        }

        apiReturn(1, 'AI一键优化完成', $list);
    }


    /**
     * 保存私信内容
     * */
    public function saveChat()
    {
        $input = Request()->param();

        $id = $input['id'];
        $msg = $input['msg'];

        if (empty($id)) apiReturn(2, 'ID缺失');
        if (empty($msg)) apiReturn(2, '回复内容缺失');

        Db::name('chat_user')->where(['id' => $id])->setField('AIMsg', $msg);
        apiReturn(1, '保存成功');
    }


    /**
     * 一键发送私信
     * */
    public function sendChatMsgAll()
    {
        $input = Request()->param();

        $ids = $input['ids'];

        if (empty($ids)) apiReturn(2, '请选择需要优化评论');

        $where['id'] = ['in', $ids];

        $list = Db::name('chat_user')->where($where)->order('new_msg_time desc')->select();
        if ($list) {
            foreach ($list as &$v) {
                if (empty($v['sessionId']) && empty($v['AIMsg'])) continue;

                $response = $this->sendChatMsg($v['sessionId'], $v['AIMsg']);
                // 输出响应结果
                $return_data = json_decode($response, true);
                if ($return_data['errCode'] == 0) {
                    sleep(3);
                } else {
                    continue;
                }
            }
        }

        apiReturn(1, '一键私信完成');
    }

    /**
     * 发送私信消息
     * @param        $friend_sessionId
     * @param        $content
     * @param string $login_sessionId 当前登录账号sessionId，也是消息发送者的sessionId
     * @param int    $chat_msg_id     被回复消息的id，chat_msg的主键id
     * */
    public function sendChatMsg($friend_sessionId, $content, $login_sessionId = '', $chat_msg_id = 0)
    {
        // 设置请求 URL
        $url = "https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/private-msg/send-private-msg?_rid=676c031a-50e2552f";

        $uuid = Guid::uuid4()->toString();

        $login_sessionId = $login_sessionId ? : $this->sessionId;

        // 设置 POST 数据
        $me_sessionId = "v2_{$login_sessionId}@finder";
        $msgPack = [
            "cliMsgId" => $uuid,
            "fromUsername" => $me_sessionId,
            "msgType" => 1,
            "sessionId" => $friend_sessionId . '@findermsg',
            "textMsg" => [
                "content" => $content
            ],
            "toUsername" => "fv1_{$friend_sessionId}@findermsgstranger",
        ];

        $data = [
            "msgPack" => $msgPack,
            "pluginSessionId" => null,
            "rawKeyBuff" => null,
            "reqScene" => 7,
            "scene" => 7,
            "timestamp" => round(microtime(true) * 1000),
            "_log_finder_id" => $me_sessionId,
            "_log_finder_uin" => ""
        ];


        // 将数据编码为 JSON 格式
        $jsonData = json_encode($data);

        $response = $this->sendCurl($url, $jsonData, 2);
        if ($response === false) apiReturn(2, '当前视频号凭证已过期');

        $return_data = json_decode($response, true);
        if ($return_data['errCode'] != 0) return false;

        Db::name('chat_msg')->where(['id' => $chat_msg_id])->setField('auto_chat_msg', $content);

        return $return_data;
    }

    // 发送私信消息接口
    public function sendPrivateMsg()
    {
        $input = Request()->param();

        $user_id = $input['user_id'];
        $msg = $input['msg'];
        $quick_id = $input['quick_id'] ? : 0;

        if (empty($user_id)) apiReturn(2, '发送消息失败');
        if (empty($msg)) apiReturn(2, '请输入消息内容');

        $user_info = Db::name('chat_user')->where('id', $user_id)->find();
        if (empty($user_info)) apiReturn(2, '用户不存在');

        $friend_sessionId = $user_info['sessionId'];
        if (empty($friend_sessionId)) apiReturn(2, '发送消息失败');

        $data = $this->sendChatMsg($friend_sessionId, $msg);
        if ($data) {
            if ($quick_id) Db::name('quick_reply')->where(['id' => $quick_id])->setInc('use_count');

            $msg_data = [
                'login_sessionId' => $this->sessionId,
                'fromUsername' => "v2_{$this->sessionId}@finder",
                'msgType' => 1,
                'rawContent' => $msg,
                'sessionId' => "{$friend_sessionId}@findermsg",
                'svrMsgId' => $data['data']['svrMsgId'],
                'toUsername' => "fv1_{$friend_sessionId}@findermsgstranger",
                'ts' => time(),
                'imgMsg' => '',
                'img' => 0,
            ];
            Db::name('chat_msg')->insert($msg_data);

            apiReturn(1, '发送消息成功');
        } else {
            apiReturn(2, '发送消息失败');
        }
    }

    /**
     * 获取当前视频号登录cookie
     * */
    public function getLoginCookie()
    {
        $input = Request()->param();

        $id = $input['id'];

        if (empty($id)) apiReturn(2, '账号ID缺失');

        $info = Db::name('account')->where('id', $id)->find();
        if (empty($info)) apiReturn(2, '账号不存在');

        // 设置请求 URL
        $url = "https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/private-msg/get-login-cookie";

        // 设置 POST 数据
        $me_sessionId = "v2_{$this->sessionId}@finder";

        $data = [
            "pluginSessionId" => null,
            "rawKeyBuff" => null,
            "reqScene" => 7,
            "scene" => 7,
            "timestamp" => round(microtime(true) * 1000),
            "_log_finder_id" => $me_sessionId,
            "_log_finder_uin" => ""
        ];


        // 将数据编码为 JSON 格式
        $jsonData = json_encode($data);

        $response = $this->sendCurl($url, $jsonData, 2);
        if ($response === false) apiReturn(2, '当前视频号凭证已过期');

        $return_data = json_decode($response, true);
        if ($return_data['errCode'] != 0) return false;

        if (!$info['apiLoginCookie']) Db::name('account')->where('id', $id)->setField('apiLoginCookie', $return_data['data']['cookie']);

        apiReturn(1, '成功');
    }


    /**
     * 获取新消息
     * */
    public function getNewMsg()
    {
        file_put_contents(RUNTIME_PATH . 'shell.txt', '开始执行getNewMsg；' . date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);

        $list = Db::name('account')
            ->where('sessionId', '<>', '')
            ->where('cookie', '<>', '')
            ->where(function ($query) {
                $query->where('apiLoginCookie', '<>', '')->whereOr('apiLoginCookie2', '<>', '');
            })
            ->where('is_auto_chat', 1)
            ->select();

        if ($list) {
            foreach ($list as &$v) {
                $info = Db::name('account')->where('id', $v['id'])->find();
                if (empty($info)) continue;

                $apiCookie = $info['apiLoginCookie2'] ? : $info['apiLoginCookie'];
                if (empty($apiCookie)) continue;

                // 设置请求 URL
                $url = "https://channels.weixin.qq.com/micro/interaction/cgi-bin/mmfinderassistant-bin/private-msg/get-new-msg";

                // 设置 POST 数据
                $me_sessionId = "v2_{$info['sessionId']}@finder";

                $data = [
                    "cookie" => $apiCookie,
                    "pluginSessionId" => null,
                    "rawKeyBuff" => null,
                    "reqScene" => 7,
                    "scene" => 7,
                    "timestamp" => round(microtime(true) * 1000),
                    "_log_finder_id" => $me_sessionId,
                    "_log_finder_uin" => ""
                ];

                // 将数据编码为 JSON 格式
                $jsonData = json_encode($data);

                $response = $this->sendCurl($url, $jsonData, 2);
                if ($response === false) {
                    Db::name('account')->where('id', $v['id'])->setField('is_auto_chat', 0);
                    continue;
                }

                $return_data = json_decode($response, true);

                if ($return_data['errCode'] != 0) {
                    Db::name('account')->where('id', $v['id'])->setField('is_auto_chat', 0);
                    continue;
                }

                if (!$info['apiLoginCookie2']) Db::name('account')->where('id', $v['id'])->setField('apiLoginCookie2', $return_data['data']['cookie']);

                if ($msg_list = $return_data['data']['msg']) {
                    file_put_contents(RUNTIME_PATH . 'shell.txt', 'insertAllChatMsg => sessionId = ' . $info['sessionId'] . PHP_EOL, FILE_APPEND);

                    $this->insertAllChatMsg($msg_list, $info['sessionId']);

                    // 从新消息中获取需要等待被回复的消息
                    $wait_svrMsgId_list = [];
                    foreach ($msg_list as &$v) {
                        if ($v['msgType'] == 1 && $v['toUsername'] == $me_sessionId) {
                            $wait_svrMsgId_list[] = $v['svrMsgId'];
                        }
                    }

                    $quick_reply_list = Db::name('quick_reply')->field('id,keyword')->where('user_id', $info['user_id'])->where('pid', 0)->order('sort asc')->select();
                    if ($wait_svrMsgId_list && $quick_reply_list) {
                        $chat_msg_list = Db::name('chat_msg')->where('svrMsgId', 'in', $wait_svrMsgId_list)->where('auto_chat_msg', null)->select();
                        if ($chat_msg_list) {
                            foreach ($chat_msg_list as &$v) {
                                // 发送私信消息
                                foreach ($quick_reply_list as $val) {
                                    if (strpos($v['rawContent'], $val['keyword']) !== false) {
                                        // 匹配成功，发送回复消息
                                        $msg = Db::name('quick_reply')->where('pid', $val['id'])->value('msg');
                                        if ($msg) {
                                            $friend_sessionId = str_replace(['fv1_', '@findermsgstranger'], '', $v['fromUsername']);
                                            file_put_contents(RUNTIME_PATH . 'shell.txt', 'sendChatMsg => sessionId = ' . $info['sessionId'] . '；friend_sessionId = ' . $friend_sessionId . PHP_EOL, FILE_APPEND);
                                            $this->sendChatMsg($friend_sessionId, $msg, $info['sessionId'], $v['id']);
                                            break;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}


